home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / cxref_1_4a.lha / preproc.c < prev    next >
C/C++ Source or Header  |  1997-12-07  |  9KB  |  382 lines

  1. /***************************************
  2.   $Header: /home/amb/cxref/RCS/preproc.c 1.13 1997/07/25 19:10:11 amb Exp $
  3.  
  4.   C Cross Referencing & Documentation tool. Version 1.4a.
  5.  
  6.   Collects the pre-processing instruction stuff.
  7.   ******************/ /******************
  8.   Written by Andrew M. Bishop
  9.  
  10.   This file Copyright 1995,96,97 Andrew M. Bishop
  11.   It may be distributed under the GNU Public License, version 2, or
  12.   any higher version.  See section COPYING of the GNU Public license
  13.   for conditions under which this file may be redistributed.
  14.   ***************************************/
  15.  
  16. /*+ Control the output of debugging information for this file. +*/
  17. #define DEBUG 0
  18.  
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23.  
  24. #include <sys/stat.h>
  25.  
  26. #ifdef AMIGA /* olsen */
  27. #include "amiga.h"
  28. #endif /* AMIGA */
  29.  
  30. #include "memory.h"
  31. #include "datatype.h"
  32. #include "cxref.h"
  33.  
  34. /*+ The file that is currently being processed. +*/
  35. extern File CurFile;
  36.  
  37. /*+ The name of the include directories specified on the command line. +*/
  38. extern char **option_incdirs;
  39.  
  40. /*+ The number of include directories on the command line. +*/
  41. extern int option_nincdirs;
  42.  
  43. /*+ When in a header file, this is set to 1, to allow most of the stuff to be skipped. +*/
  44. int in_header=0;
  45.  
  46. /*+ The current #include we are looking at. +*/
  47. static Include cur_inc=NULL;
  48.  
  49. /*+ The current #define we are looking at. +*/
  50. static Define cur_def=NULL;
  51.  
  52. /*+ The depth of includes. +*/
  53. static int inc_depth=0;
  54.  
  55. /*+ The type of include at this depth. +*/
  56. static char *inc_type=NULL;
  57.  
  58. /*+ The working directory. +*/
  59. static char *cwd=NULL;
  60.  
  61.  
  62. static Include NewIncludeType(char *name);
  63. static Define NewDefineType(char *name);
  64.  
  65.  
  66. /*++++++++++++++++++++++++++++++++++++++
  67.   Function that is called when an included file is seen in the current file.
  68.  
  69.   char *name The name of the file from the source code.
  70.   ++++++++++++++++++++++++++++++++++++++*/
  71.  
  72. void SeenInclude(char *name)
  73. {
  74. #if DEBUG
  75.  printf("#Preproc.c# #include %s\n",name);
  76. #endif
  77.  
  78.  if(!inc_type || inc_depth==0 || inc_type[inc_depth-1]==LOCAL)
  79.    {
  80.     Include inc,*t=&CurFile->includes;
  81.     int inc_scope=(*name=='"')?LOCAL:GLOBAL;
  82.     int i;
  83.  
  84.     name++;
  85.     name[strlen(name)-1]=0;
  86.  
  87.     if(inc_scope==LOCAL && option_nincdirs)
  88.        for(i=0;i<option_nincdirs;i++)
  89.          {
  90.           char *newname=CanonicaliseName(ConcatStrings(3,option_incdirs[i],"/",name));
  91.           struct stat buf;
  92.  
  93.           if(!lstat(newname,&buf))
  94.             {name=newname;break;}
  95.          }
  96.  
  97.     for(i=0;i<inc_depth;i++)
  98.       {
  99.        while(*t && (*t)->next)
  100.           t=&(*t)->next;
  101.        t=&(*t)->includes;
  102.       }
  103.  
  104.     inc=NewIncludeType(name);
  105.  
  106.     inc->comment=MallocString(GetCurrentComment());
  107.     inc->scope=inc_scope;
  108.  
  109.     AddToLinkedList(*t,Include,inc);
  110.  
  111.     cur_inc=inc;
  112.    }
  113.  else
  114.     cur_inc=NULL;
  115. }
  116.  
  117.  
  118. /*++++++++++++++++++++++++++++++++++++++
  119.   Function that is called when a comment is seen following a #include.
  120.   ++++++++++++++++++++++++++++++++++++++*/
  121.  
  122. void SeenIncludeComment(void)
  123. {
  124.  char* comment=GetCurrentComment();
  125.  
  126. #if DEBUG
  127.  printf("#Preproc.c# #include trailing comment '%s' for %s\n",comment,cur_inc->name);
  128. #endif
  129.  
  130.  if(!cur_inc->comment)
  131.     cur_inc->comment=MallocString(comment);
  132. }
  133.  
  134.  
  135. /*++++++++++++++++++++++++++++++++++++++
  136.   Function that is called when a change in current file is seen.
  137.  
  138.   char *name The pathname of the included file as determined by gcc.
  139.  
  140.   int flag The flags that GCC leaves in the file
  141.   ++++++++++++++++++++++++++++++++++++++*/
  142.  
  143. void SeenFileChange(char *name,int flag)
  144. {
  145.  if(!cwd)
  146.    {
  147.     cwd=(char*)Malloc(256);
  148.     if(!getcwd(cwd,255))
  149.        cwd[0]=0;
  150.    }
  151.  
  152. #if DEBUG
  153.  printf("#Preproc.c# FileChange - %s %s (flag=%d)\n",flag&2?"Included ":"Return to",name,flag);
  154. #endif
  155.  
  156.  name=CanonicaliseName(name);
  157.  
  158.  if(!strncmp(name,cwd,strlen(cwd)))
  159.     name=name+strlen(cwd);
  160.  
  161.  /* Store the information. */
  162.  
  163.  if(flag&2 && (!inc_type || inc_depth==0 || inc_type[inc_depth-1]==LOCAL) && !cur_inc)
  164.     if(flag&8)
  165.        SeenInclude(ConcatStrings(3,"<",name,">"));
  166.     else
  167.        SeenInclude(ConcatStrings(3,"\"",name,"\""));
  168.  
  169.  cur_inc=NULL;
  170.  
  171.  if(flag&2)
  172.    {
  173.     inc_depth++;
  174.  
  175.     if(!inc_type)
  176.        inc_type=(char*)Malloc(16);
  177.     else
  178.        if(!(inc_depth%16))
  179.           inc_type=(char*)Realloc(inc_type,(unsigned)(inc_depth+16));
  180.  
  181.     if(inc_depth>1 && inc_type[inc_depth-2]==GLOBAL)
  182.        inc_type[inc_depth-1]=GLOBAL;
  183.     else
  184.        inc_type[inc_depth-1]=(flag&8)?GLOBAL:LOCAL;
  185.    }
  186.  else
  187.     inc_depth--;
  188.  
  189.  if(inc_type && inc_depth>0)
  190.     in_header=inc_type[inc_depth-1];
  191.  else
  192.     in_header=0;
  193. }
  194.  
  195.  
  196. /*++++++++++++++++++++++++++++++++++++++
  197.   Function that is called when a #define is seen in the current file.
  198.  
  199.   char* name The name of the #defined symbol.
  200.   ++++++++++++++++++++++++++++++++++++++*/
  201.  
  202. void SeenDefine(char* name)
  203. {
  204.  Define def;
  205.  
  206. #if DEBUG
  207.  printf("#Preproc.c# Defined name '%s'\n",name);
  208. #endif
  209.  
  210.  def=NewDefineType(name);
  211.  
  212.  def->comment=MallocString(GetCurrentComment());
  213.  
  214.  AddToLinkedList(CurFile->defines,Define,def);
  215.  
  216.  cur_def=def;
  217. }
  218.  
  219.  
  220. /*++++++++++++++++++++++++++++++++++++++
  221.   Function that is called when a comment is seen in a #define definition.
  222.   ++++++++++++++++++++++++++++++++++++++*/
  223.  
  224. void SeenDefineComment(void)
  225. {
  226.  char* comment=GetCurrentComment();
  227.  
  228. #if DEBUG
  229.  printf("#Preproc.c# #define inline comment '%s' in %s\n",comment,cur_def->name);
  230. #endif
  231.  
  232.  if(!cur_def->comment)
  233.     cur_def->comment=MallocString(comment);
  234. }
  235.  
  236.  
  237. /*++++++++++++++++++++++++++++++++++++++
  238.   Function that is called when a #define value is seen in the current file.
  239.  
  240.   char* value The value of the #defined symbol.
  241.   ++++++++++++++++++++++++++++++++++++++*/
  242.  
  243. void SeenDefineValue(char* value)
  244. {
  245. #if DEBUG
  246.  printf("#Preproc.c# #define value '%s' for %s\n",value,cur_def->name);
  247. #endif
  248.  
  249.  cur_def->value=MallocString(value);
  250. }
  251.  
  252.  
  253. /*++++++++++++++++++++++++++++++++++++++
  254.   Function that is called when a #define function argument is seen in the current definition.
  255.  
  256.   char* name The argument.
  257.   ++++++++++++++++++++++++++++++++++++++*/
  258.  
  259. void SeenDefineFunctionArg(char* name)
  260. {
  261. #if DEBUG
  262.  printf("#Preproc.c# #define Function arg '%s' in %s()\n",name,cur_def->name);
  263. #endif
  264.  
  265.  AddToStringList2(cur_def->args,name,SplitComment(&cur_def->comment,name),0,0);
  266. }
  267.  
  268.  
  269. /*++++++++++++++++++++++++++++++++++++++
  270.   Function that is called when a comment is seen in a #define function definition.
  271.   ++++++++++++++++++++++++++++++++++++++*/
  272.  
  273. void SeenDefineFuncArgComment(void)
  274. {
  275.  char* comment=GetCurrentComment();
  276.  
  277. #if DEBUG
  278.  printf("#Preproc.c# #define Function arg comment '%s' in %s()\n",comment,cur_def->name);
  279. #endif
  280.  
  281.  if(!cur_def->args->s2[cur_def->args->n-1])
  282.     cur_def->args->s2[cur_def->args->n-1]=MallocString(comment);
  283. }
  284.  
  285.  
  286. /*++++++++++++++++++++++++++++++++++++++
  287.   Tidy up all of the local variables in case of a problem and abnormal parser termination.
  288.   ++++++++++++++++++++++++++++++++++++++*/
  289.  
  290. void ResetPreProcAnalyser(void)
  291. {
  292.  in_header=0;
  293.  
  294.  cur_inc=NULL;
  295.  cur_def=NULL;
  296.  
  297.  inc_depth=0;
  298.  
  299.  if(inc_type) Free(inc_type);
  300.  inc_type=NULL;
  301.  
  302.  if(cwd) Free(cwd);
  303.  cwd=NULL;
  304. }
  305.  
  306.  
  307. /*++++++++++++++++++++++++++++++++++++++
  308.   Create a new Include datatype.
  309.  
  310.   Include NewIncludeType Return the new Include type.
  311.  
  312.   char *name The name of the new include.
  313.   ++++++++++++++++++++++++++++++++++++++*/
  314.  
  315. static Include NewIncludeType(char *name)
  316. {
  317.  Include inc=(Include)Calloc(1,sizeof(struct _Include));
  318.  
  319.  inc->name=MallocString(name);
  320.  
  321.  return(inc);
  322. }
  323.  
  324.  
  325. /*++++++++++++++++++++++++++++++++++++++
  326.   Delete the specified Include type.
  327.  
  328.   Include inc The Include type to be deleted.
  329.   ++++++++++++++++++++++++++++++++++++++*/
  330.  
  331. void DeleteIncludeType(Include inc)
  332. {
  333.  if(inc->comment) Free(inc->comment);
  334.  if(inc->name)    Free(inc->name);
  335.  if(inc->includes)
  336.    {
  337.     Include p=inc->includes;
  338.     do{
  339.        Include n=p->next;
  340.        DeleteIncludeType(p);
  341.        p=n;
  342.       }
  343.     while(p);
  344.    }
  345.  Free(inc);
  346. }
  347.  
  348.  
  349. /*++++++++++++++++++++++++++++++++++++++
  350.   Create a new Define datatype.
  351.  
  352.   Define NewDefineType Return the new Define type.
  353.  
  354.   char *name The name of the new define.
  355.   ++++++++++++++++++++++++++++++++++++++*/
  356.  
  357. static Define NewDefineType(char *name)
  358. {
  359.  Define def=(Define)Calloc(1,sizeof(struct _Define));
  360.  
  361.  def